﻿using System;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Xml;
using System.IO;

namespace uk.org.aspellclark.todolistppc
{
    public partial class frmMain2 : Form
    {
        #region Member Variables

        private const string M_NEW_TASK_NAME = "New Task";

        private PreferencesXml m_preferences = null;
        private TodoListTreeNode m_SelectedNode = null;
        private bool m_bEncrypt = false;
        private bool m_bStarting = false;
        private string m_strFile = "TodoList.xml";
        private int m_iLevel;
        private CTask m_selectedTask;
        private bool m_bLoadingData = false;
        private bool m_bDataChanged = false;
        private bool m_bNodeDataChanged = false;


        private string m_sFileFormat = "6";
        private string m_sProjectName = null;
        private Int16 m_iNextUniqueID = -1;
        private string m_sFileVersion = "1";
        private string m_sLastModified = null;
        private string m_sLastSortBy = null;
        private string m_sLastSortDir = null;
        private DateTime m_dtEarliestDueDate;

        private System.Drawing.Font m_Font;
        private string m_sCurrFontSize = "VSmall";
        private Hashtable m_htFontSizes = new Hashtable();

        #endregion


        #region Properties
        private bool DataChanged
        {
            get { return m_bDataChanged; }
            set { m_bDataChanged = value; }
        }
        private bool LoadingData
        {
            get { return m_bLoadingData; }
            set { m_bLoadingData = value; }
        }
        #endregion



        public frmMain2()
        {
            m_htFontSizes.Add("VSmall", 8);
            m_htFontSizes.Add("Small", 10);
            m_htFontSizes.Add("Normal", 12);
            m_htFontSizes.Add("Large", 14);
            m_htFontSizes.Add("VLarge", 16);
            m_sCurrFontSize = "VSmall";
            m_Font = new Font("Tahoma", (int)m_htFontSizes[m_sCurrFontSize], FontStyle.Regular);

            m_preferences = new PreferencesXml();
            LoadPreferences();

            LoadLastFile();

            m_bStarting = true;
            InitializeComponent();
        }

        private void LoadLastFile()
        {
            String oldFileName = m_preferences.getPreference("LastOpenedFile");
            if (oldFileName == null | oldFileName == "" || oldFileName.Length == 0)
            {
                //no last file name stored
            }
            else
            {
                if (File.Exists(oldFileName))
                {
                    m_strFile = oldFileName;
                    FillTree();
                    LoadingData = false;
                }
            }
        }

        #region Menu Callbacks
        private void mnuToolsOpen_Click(object sender, EventArgs e)
        {
            DialogResult saveChanges = DialogResult.Yes;
            if (DataChanged)
            {
                //ask to lose changes???
                saveChanges = MessageBox.Show("Save Changes you have made to this todo list?", "Save Changes?", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
            }
            else
            {
                saveChanges = DialogResult.No;
            }

            if (saveChanges == DialogResult.Yes)
            {
                if (m_strFile == "")
                {
                    SaveAs();
                }
                else
                {
                    writeTodoListFile();
                }
            }
            OpenFileDialog ofdTodoList = new OpenFileDialog();

            ofdTodoList.InitialDirectory = "" + System.IO.Path.DirectorySeparatorChar;
            ofdTodoList.Filter = "Todolist files (*.xml,*.tdl)|*.xml,*.tdl|All files (*.*)|*.*";
            ofdTodoList.FilterIndex = 1;

            if (ofdTodoList.ShowDialog() == DialogResult.OK)
            {
                LoadingData = true;
                m_strFile = ofdTodoList.FileName;
                SetPref("LastOpenedFile", m_strFile);
                DataChanged = false;
                FillTree();
                LoadingData = false;
            }
            DataChanged = false;
        }

        private void mnuToolsClose_Click(object sender, EventArgs e)
        {

        }

        private void mnuToolsSave_Click(object sender, EventArgs e)
        {
            if (m_strFile == "")
            {
                SaveAs();
            }
            else
            {
                writeTodoListFile();
            }
        }

        private void mnuToolsSaveAs_Click(object sender, EventArgs e)
        {
            DataChanged = true;
            SaveAs();
        }

        private void mnuToolsExit_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void mnuHelpAbout_Click(object sender, EventArgs e)
        {
            using (FrmAboutBox frmObj = new FrmAboutBox())
            {
                frmObj.AppTitle = "ToDoListPPC";
                frmObj.AppDescription = "Pocket PC Todolist";
                string sTmpText = this.Text;
                this.Text = "";
                frmObj.Text = sTmpText;
                frmObj.ShowDialog();
                this.Text = sTmpText;
                frmObj.Dispose();
            }
        }

        private void mnuViewAll_Click(object sender, EventArgs e)
        {
            SetViewFilter(0);
        }

        private void mnuViewActive_Click(object sender, EventArgs e)
        {
            SetViewFilter(1);
        }

        private void mnuViewComplete_Click(object sender, EventArgs e)
        {
            SetViewFilter(2);
        }

        private void mnuViewDetails_Click(object sender, EventArgs e)
        {

        }

        private void mnuViewRefresh_Click(object sender, EventArgs e)
        {
            FillTree();
        }

        private void mnuNewTask_Click(object sender, EventArgs e)
        {
            CTask tmpTask = new CTask();
            tmpTask.TaskId = m_iNextUniqueID++;
            tmpTask.Title = M_NEW_TASK_NAME;

            TodoListTreeNode newNode = new TodoListTreeNode(M_NEW_TASK_NAME);
            newNode.Task = tmpTask;
            newNode.TaskId = tmpTask.TaskId;
            DataChanged = true;

            m_tvTodoList.Nodes.Add(newNode);
        }
        #endregion


        #region Widget Callbacks

        private void m_tvTodoList_AfterSelect(object sender, TreeViewEventArgs e)
        {
            TodoListTreeNode tlNode = e.Node as TodoListTreeNode;
            if (m_SelectedNode != null && m_bNodeDataChanged)
            {
                //save changes to node
            }
            if (tlNode.Task != null)
            {
                m_selectedTask = tlNode.Task;

                if (m_selectedTask.Priority > 0)
                {
                    m_tbxPriority.Text = m_selectedTask.Priority.ToString();
                }
                else
                {
                    m_tbxPriority.Text = "";
                }

                if (m_selectedTask.HoursEst > 0)
                {
                    txtTimeEstimate.Text = m_selectedTask.HoursEst.ToString();
                }
                else
                {
                    txtTimeEstimate.Text = "";
                }

                if (m_selectedTask.PercentComplete > 0)
                {
                    m_tbxPercentComplete.Text = m_selectedTask.PercentComplete.ToString();
                }
                else
                {
                    m_tbxPercentComplete.Text = "";
                }
                txtTitle.Text = m_selectedTask.Title;
                txtAllocatedTo.Text = m_selectedTask.AllocatedTo;

                m_tbxStartDate.Text = m_selectedTask.StartDateStr;
                m_tbxDueDate.Text = m_selectedTask.DueDateStr;
                m_tbxCompletedDate.Text = m_selectedTask.DoneDateStr;

                txtNotes.Text = m_selectedTask.CommentsStr;
            }
        }


        private void txtTitle_TextChanged(object sender, EventArgs e)
        {
            TodoListTreeNode selectedNode = m_tvTodoList.SelectedNode as TodoListTreeNode;
            CTask tmpTask = selectedNode.Task;
            tmpTask.Title = txtTitle.Text;
            selectedNode.Text = tmpTask.Title;
            DataChanged = true;
        }

        private void txtTitle_GotFocus(object sender, EventArgs e)
        {

        }

        private void txtAllocatedTo_TextChanged(object sender, EventArgs e)
        {

        }

        private void m_tbxPercentComplete_TextChanged(object sender, EventArgs e)
        {
            TodoListTreeNode selectedNode = m_tvTodoList.SelectedNode as TodoListTreeNode;
            CTask tmpTask = selectedNode.Task;
            try { tmpTask.PercentComplete = Convert.ToInt16(m_tbxPercentComplete.Text); }
            catch { }
            if (tmpTask.Complete) { selectedNode.ImageIndex = 1; selectedNode.SelectedImageIndex = 1; }
            DataChanged = true;
        }

        private void m_tbxPriority_TextChanged(object sender, EventArgs e)
        {
            TodoListTreeNode selectedNode = m_tvTodoList.SelectedNode as TodoListTreeNode;
            CTask tmpTask = selectedNode.Task;
            try { tmpTask.Priority = Convert.ToInt16(m_tbxPriority.Text); }
            catch { }
            DataChanged = true;
        }

        private void m_tbxCompletedDate_TextChanged(object sender, EventArgs e)
        {
            TodoListTreeNode selectedNode = m_tvTodoList.SelectedNode as TodoListTreeNode;
            CTask tmpTask = selectedNode.Task;
            //try { tmpTask.DoneDate = new DateTime(m_tbxCompletedDate.Text); } catch {}
            DataChanged = true;
        }

        private void m_tbxDueDate_TextChanged(object sender, EventArgs e)
        {

        }

        private void m_tbxStartDate_TextChanged(object sender, EventArgs e)
        {

        }

        private void txtNotes_TextChanged(object sender, EventArgs e)
        {
            TodoListTreeNode selectedNode = m_tvTodoList.SelectedNode as TodoListTreeNode;
            CTask tmpTask = selectedNode.Task;
            tmpTask.CommentsStr = txtNotes.Text;
            DataChanged = true;
        }

        private void m_cmbSortBy_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void m_cmbSortDirection_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void m_tbxProjectName_TextChanged(object sender, EventArgs e)
        {
            m_sProjectName = m_tbxProjectName.Text;
            m_lblProject.Text = m_sProjectName;
            if (!LoadingData)
            {
                DataChanged = true;
            }
        }

        private void m_tvTodoList_AfterCheck(object sender, TreeViewEventArgs e)
        {
            TodoListTreeNode tlNode = e.Node as TodoListTreeNode;
            tlNode.Clicked(tlNode.Checked);

            TodoListTreeNode selectedNode = m_tvTodoList.SelectedNode as TodoListTreeNode;
            if ((selectedNode != null) && (selectedNode.TaskId == tlNode.TaskId))
            {
                if (tlNode.Task.PercentComplete > 0)
                {
                    m_tbxPercentComplete.Text = tlNode.Task.PercentComplete.ToString();
                }
                else
                {
                    m_tbxPercentComplete.Text = "";
                }
            }

            DataChanged = true;
        }

        #endregion

        #region Preferences
        private void SetPref(string psName, string psValue)
        {
            m_preferences.setPreference(psName, psValue);
            SavePreferences();
        }
        private string GetPref(string psName)
        {
            return m_preferences.getPreference(psName);
        }
        private void SavePreferences()
        {
            m_preferences.writeToFile();
        }
        private void LoadPreferences()
        {
            m_preferences.readFromFile();
        }
        #endregion


        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            TodoListTreeNode tlNode = e.Node as TodoListTreeNode;
            if (m_SelectedNode != null && m_bNodeDataChanged)
            {
                //save changes to node
            }
            if (tlNode.Task != null)
            {
                m_selectedTask = tlNode.Task;

                if (m_selectedTask.Priority > 0)
                {
                    m_tbxPriority.Text = m_selectedTask.Priority.ToString();
                }
                else
                {
                    m_tbxPriority.Text = "";
                }

                if (m_selectedTask.HoursEst > 0)
                {
                    txtTimeEstimate.Text = m_selectedTask.HoursEst.ToString();
                }
                else
                {
                    txtTimeEstimate.Text = "";
                }

                if (m_selectedTask.PercentComplete > 0)
                {
                    m_tbxPercentComplete.Text = m_selectedTask.PercentComplete.ToString();
                }
                else
                {
                    m_tbxPercentComplete.Text = "";
                }
                txtTitle.Text = m_selectedTask.Title;
                txtAllocatedTo.Text = m_selectedTask.AllocatedTo;

                m_tbxStartDate.Text = m_selectedTask.StartDateStr;
                m_tbxDueDate.Text = m_selectedTask.DueDateStr;
                m_tbxCompletedDate.Text = m_selectedTask.DoneDateStr;

                txtNotes.Text = m_selectedTask.CommentsStr;
            }
        }

        private void frmMain2_Closing(object sender, CancelEventArgs e)
        {
            DialogResult saveChanges = DialogResult.Yes;
            if (DataChanged)
            {
                //ask to lose changes???
                saveChanges = MessageBox.Show("Save Changes you have made to this todo list?", "Save Changes?", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
            }
            else
            {
                saveChanges = DialogResult.No;
            }

            if (saveChanges == DialogResult.Yes)
            {
                if (m_strFile == "")
                {
                    SaveAs();
                }
                else
                {
                    writeTodoListFile();
                }
            }
        }

        private void SaveAs()
        {
            SaveFileDialog sfdTodoList = new SaveFileDialog();

            //sfdTodoList.InitialDirectory = "" + System.IO.Path.DirectorySeparatorChar;
            sfdTodoList.Filter = "Todolist files (*.tdl,*.xml)|*.tdl;*.xml|All files (*.*)|*.*";
            sfdTodoList.FilterIndex = 1;
            sfdTodoList.FileName = m_strFile;

            if (sfdTodoList.ShowDialog() == DialogResult.OK)
            {
                m_strFile = sfdTodoList.FileName;
                m_sProjectName = m_strFile;
                writeTodoListFile();
            }
        }

        private void writeTodoListFile()
        {
            if (m_strFile == "")
            {
                m_strFile = "TodoList.xml";
            }
            if (DataChanged == true)
            {
                if (File.Exists(m_strFile))
                {
                    if (File.Exists(m_strFile + ".bak"))
                    {
                        File.Delete(m_strFile + ".bak");
                    }
                    File.Move(m_strFile, m_strFile + ".bak");
                }
                XmlTextWriter xmlWriter = new XmlTextWriter(m_strFile, System.Text.Encoding.UTF8);

                xmlWriter.Formatting = Formatting.Indented;
                xmlWriter.Indentation = 0;
                xmlWriter.IndentChar = ' ';

                xmlWriter.WriteStartDocument();

                if (m_bEncrypt)
                {
                    //writeOutEncryptedFile();
                }
                else
                {
                    //write out the root element - Project
                    xmlWriter.WriteStartElement("TODOLIST");

                    xmlWriter.WriteAttributeString("", "FILEFORMAT", "", m_sFileFormat);
                    xmlWriter.WriteAttributeString("", "PROJECTNAME", "", m_sProjectName);
                    xmlWriter.WriteAttributeString("", "NEXTUNIQUEID", "", m_iNextUniqueID.ToString());
                    xmlWriter.WriteAttributeString("", "EARLIESTDUEDATE", "", CommonFunctions.DateTimeToOleDate(m_dtEarliestDueDate).ToString());

                    int iFileVer = Convert.ToInt32(m_sFileVersion);
                    iFileVer++;
                    m_sFileVersion = iFileVer.ToString();
                    xmlWriter.WriteAttributeString("", "FILEVERSION", "", m_sFileVersion);

                    m_sLastModified = DateTime.Now.ToString("yyyy-mm-dd");
                    xmlWriter.WriteAttributeString("", "LASTMODIFIED", "", m_sLastModified);


                    //write out the tree nodes

                    foreach (TodoListTreeNode tmpNode in m_tvTodoList.Nodes)
                    {
                        OutputNodes(xmlWriter, tmpNode);
                    }

                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteEndDocument();
                    xmlWriter.Flush();
                    xmlWriter.Close();
                    DataChanged = false;

                    m_lblProject.Text = m_sProjectName + " [v" + m_sFileVersion + " - " + m_sLastModified + "]";
                }//if (m_bEncrypt)
            }//if (DataChanged)
        }

        private void OutputNodes(XmlTextWriter pXmlWriter, TodoListTreeNode pNode)
        {
            CTask currTask = pNode.Task;
            currTask.writeToXml(pXmlWriter);
            foreach (TodoListTreeNode tmpNode in pNode.Nodes)
            {
                OutputNodes(pXmlWriter, tmpNode);
            }
            currTask.endWriteToXml(pXmlWriter);
        }

        private void SetViewFilter(Int16 iLevel)
        {
            mnuViewAll.Checked = false;
            mnuViewActive.Checked = false;
            mnuViewComplete.Checked = false;

            if (iLevel == 0)
            {
                mnuViewAll.Checked = true;
            }
            else if (iLevel == 1)
            {
                mnuViewActive.Checked = true;
            }
            else if (iLevel == 2)
            {
                mnuViewComplete.Checked = true;
            }

            m_iLevel = iLevel;

            FillTree();
        }

        private void FillTree()
        {
            Cursor.Current = Cursors.WaitCursor;
            DialogResult loseChanges = DialogResult.No;
            if (DataChanged)
            {
                //ask to lose changes???
                loseChanges = MessageBox.Show("Lose Changes you have made to this todo list?", "Lose Changes?", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
            }
            else
            {
                loseChanges = DialogResult.Yes;
            }

            if (loseChanges == DialogResult.Yes)
            {
                XmlDocument xmlTodoList;
                XmlNode xndList;
                TodoListTreeNode tnParent;

                try
                {
                    xmlTodoList = new XmlDocument();

                    xmlTodoList.Load(m_strFile);

                    m_tvTodoList.BeginUpdate();

                    m_tvTodoList.Nodes.Clear();

                    if (xmlTodoList.GetElementsByTagName("TODOLIST").Count > 0)
                    {
                        xndList = xmlTodoList.GetElementsByTagName("TODOLIST").Item(0);
                        m_sProjectName = xndList.Attributes.GetNamedItem("PROJECTNAME").InnerText;
                        m_tbxProjectName.Text = m_sProjectName;
                        m_sFileFormat = xndList.Attributes.GetNamedItem("FILEFORMAT").InnerText;
                        m_iNextUniqueID = Convert.ToInt16(xndList.Attributes.GetNamedItem("NEXTUNIQUEID").InnerText);
                        try { m_dtEarliestDueDate = CommonFunctions.OleDateToDateTime(Convert.ToDouble(xndList.Attributes.GetNamedItem("EARLIESTDUEDATE").InnerText)); }
                        catch { }
                        try { m_sLastSortBy = xndList.Attributes.GetNamedItem("LASTSORTBY").InnerText; }
                        catch { }
                        try { m_sFileVersion = xndList.Attributes.GetNamedItem("FILEVERSION").InnerText; }
                        catch { }
                        try { m_sLastSortDir = xndList.Attributes.GetNamedItem("LASTSORTDIR").InnerText; }
                        catch { }
                        try { m_sLastModified = xndList.Attributes.GetNamedItem("LASTMODIFIED").InnerText; }
                        catch { }

                        m_lblProject.Text = m_sProjectName + " [v" + m_sFileVersion + "]";

                        if (xndList.HasChildNodes == true)
                        {
                            for (int i = 0; i < xndList.ChildNodes.Count; i++)
                            {
                                AppendTask(null, xndList.ChildNodes.Item(i));
                            }
                        }
                    }

                    m_tvTodoList.Font = m_Font;
                    m_tvTodoList.EndUpdate();
                }
                catch (Exception e)
                {
                    tnParent = new TodoListTreeNode("Invalid Todo List File");
                    tnParent.Task = new CTask();
                    tnParent.ImageIndex = 4;
                    tnParent.SelectedImageIndex = 4;
                    m_tvTodoList.Nodes.Add(tnParent);
                    tnParent.Expand();
                }
            }
            foreach (TodoListTreeNode childNode in m_tvTodoList.Nodes)
            {
                SetChecked(childNode);
            }
            Cursor.Current = Cursors.Default;
        }

        private void SetChecked(TodoListTreeNode pNode)
        {
            if (pNode.Nodes.Count > 0)
            {
                foreach (TodoListTreeNode childNode in pNode.Nodes)
                {
                    SetChecked(childNode);
                }
            }
            CTask clsTask = pNode.Task;
            pNode.Checked = clsTask.Complete;
        }

        private void AppendTask(TodoListTreeNode tnParent, XmlNode xndTask)
        {
            TodoListTreeNode tnChild;
            CTask clsTask;

            if (xndTask.Name.ToUpper() == "TASK")
            {
                clsTask = new CTask();
                clsTask.readFromXml(xndTask);

                tnChild = new TodoListTreeNode(clsTask.Title);
                tnChild.TaskId = clsTask.TaskId;
                tnChild.Task = clsTask;
                if (tnParent != null)
                {
                    tnChild.ParentTaskId = tnParent.TaskId;
                }

                if (xndTask.HasChildNodes == true)
                {
                    for (int i = 0; i < xndTask.ChildNodes.Count; i++)
                    {
                        AppendTask(tnChild, xndTask.ChildNodes.Item(i));
                    }
                }
                tnChild.Checked = clsTask.Complete;

                if ((m_iLevel == 0) || ((m_iLevel == 1) && (clsTask.Complete == false)) || ((m_iLevel == 1) && (clsTask.Complete == true) && (tnChild.GetNodeCount(false) > 0)) || ((m_iLevel == 2) && (clsTask.Complete == true)) || ((m_iLevel == 2) && (clsTask.Complete == false) && (tnChild.GetNodeCount(false) > 0)))
                {
                    if (tnParent == null)
                    {
                        m_tvTodoList.Nodes.Add(tnChild);
                    }
                    else
                    {
                        tnParent.Nodes.Add(tnChild);
                    }
                }
            }
            else if (xndTask.Name.ToUpper() == "COMMENTS")
            {
                if (tnParent != null)
                {
                    clsTask = tnParent.Task;
                    clsTask.CommentsStr = xndTask.InnerText;
                    tnParent.Task = clsTask;
                }
            }
        }


    }
}